import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';

/** loading的颜色 */
const LOADING_COLOR = '#666';
/** loading点的个数 */
const DOT_COUNT = 8;
/** 旋转一周时长 */
const ROTATE_TIME = .65;
/** loading区域的边长 */
const SIDE_LEN = 32;
/** dot默认半径 */
const DOT_RADIUS = 2;

export interface ISpinnerProps {
  className?: string;
  style?: React.CSSProperties;
}

export class Spinner extends React.Component<ISpinnerProps, {}> {
  public static propTypes = {
    className: PropTypes.string,
    style: PropTypes.object,
  };

  public render() {
    return (
      <svg viewBox={`0 0 ${SIDE_LEN} ${SIDE_LEN}`}
        className={classNames('br-spinner', this.props.className)}
        style={this.props.style} width={SIDE_LEN} height={SIDE_LEN}>
        {
          new Array(DOT_COUNT).fill('').map((item: string, i: number) => {
            return this.renderDot(i);
          })
        }
      </svg>
    );
  }

  /**
   * 渲染spinner点
   * @param index dot索引
   */
  public renderDot(index: number) {
    const unitRadius: number = 360 / DOT_COUNT;
    const angle: number = 2 * Math.PI * (unitRadius * index) / 360;
    const runRadius: number = SIDE_LEN / 2 - 2 * DOT_RADIUS;
    const cx: number = SIDE_LEN / 2 + Math.sin(angle) * runRadius;
    const cy: number = SIDE_LEN / 2 - Math.cos(angle) * runRadius;
    return (
      <circle
        fill={LOADING_COLOR}
        cx={cx}
        cy={cy}
        r={DOT_RADIUS}
        opacity="1"
      >
        <animate
          dur={`${ROTATE_TIME}s`}
          attributeName="r"
          repeatCount="indefinite"
          begin={index * (ROTATE_TIME / DOT_COUNT)}
          values="4;3.2;2.4;2;2;2;1"
        />
        <animate
          dur={`${ROTATE_TIME}s`}
          attributeName="opacity"
          repeatCount="indefinite"
          from="1"
          to="0.1"
          begin={index * (ROTATE_TIME / DOT_COUNT)}
        />
      </circle>
    );
  }
}
